package com.xiaoshuidi.cloud.module.contract.service.contract.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fadada.sdk.base.model.req.AddSignatureParams;
import com.fadada.sdk.base.model.req.BeforeAuthSignParams;
import com.fadada.sdk.base.model.req.GetAuthStatusParams;
import com.fadada.sdk.base.model.req.RegisterAccountParams;
import com.fadada.sdk.verify.model.req.CompanyVerifyUrlParams;
import com.fadada.sdk.verify.model.req.FindCompanyCertParams;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.fadada.core.FadadaAuthServiceApi;
import com.xiaoshuidi.cloud.framework.fadada.core.FadadaContractServiceApi;
import com.xiaoshuidi.cloud.framework.fadada.core.enums.AccountTypeEnum;
import com.xiaoshuidi.cloud.framework.fadada.core.enums.FadadaReturnCodeConstants;
import com.xiaoshuidi.cloud.framework.fadada.core.service.dto.*;
import com.xiaoshuidi.cloud.module.contract.controller.admin.contract.vo.signingSubject.*;
import com.xiaoshuidi.cloud.module.contract.convert.contract.SigningSubjectConvert;
import com.xiaoshuidi.cloud.module.contract.convert.room.RoomServerConvert;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.ContractSubjectRoomRefDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.ContractTemplateDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.SigningSubjectDO;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.ContractSubjectRoomRefMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.ContractTemplateRoomMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.SigningSubjectMapper;
import com.xiaoshuidi.cloud.module.contract.enums.contract.SigningSubjectStatusEnum;
import com.xiaoshuidi.cloud.module.contract.service.contract.ContractTemplateService;
import com.xiaoshuidi.cloud.module.contract.service.contract.SigningSubjectService;
import com.xiaoshuidi.cloud.module.contract.service.contract.dto.RoomHouseRespDTO;
import com.xiaoshuidi.cloud.module.contract.util.RedisUtils;
import com.xiaoshuidi.cloud.module.contract.util.date.DateUtils;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.ApartmentApi;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.dto.ApartmentListDto;
import com.xiaoshuidi.cloud.module.rooms.api.roomhouse.RoomHouseApi;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomHouseRespVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.contract.enums.ApiConstants.*;
import static com.xiaoshuidi.cloud.module.contract.enums.ErrorCodeConstants.*;

/**
 * 合同签约主体 Service 实现类
 *
 * @author 合房租赁
 */
@Service
@Slf4j
@RefreshScope
public class SigningSubjectServiceImpl implements SigningSubjectService {
    @Value("${fadada.company_verify_notify_url}")
    private String COMPANY_VERIFY_NOTIFY_URL;
    @Value("${fadada.auto_sign_notify_url}")
    private String AUTO_SIGN_NOTIFY_URL;
    @Resource
    private SigningSubjectMapper signingSubjectMapper;
    @Resource
    private FadadaContractServiceApi fadadaContractServiceApi;
    @Resource
    private FadadaAuthServiceApi fadadaAuthServiceApi;
    @Resource
    private ContractSubjectRoomRefMapper contractSubjectRoomRefMapper;
    @Resource
    private ApartmentApi apartmentApi;
    @Resource
    private RoomHouseApi roomHouseApi;
    @Resource
    private ContractTemplateService contractTemplateService;



    @Override
    public Long createSigningSubject(SigningSubjectCreateReqVO createReqVO) {
        // 调用法大大接口
        String signatureCode = null;
        SigningSubjectDO signingSubject = null;
        try {
            signatureCode = sendGetSignatureCode(createReqVO);
        } catch (Exception e) {
            throw e;
        } finally {
            signingSubject = SigningSubjectConvert.INSTANCE.convert(createReqVO);
            if (StringUtils.isNotBlank(signatureCode)){
                signingSubject.setSignatureCode(signatureCode);
                signingSubject.setStatus(1);
                signingSubject.setActiveTime(LocalDate.now());
            }
            signingSubjectMapper.insert(signingSubject);
        }
        return signingSubject.getId();
    }

    /**
     * 查询获取法大大唯一编号
     */
    private String sendGetSignatureCode(SigningSubjectCreateReqVO createReqVO){
        // 调用法大大接口查询企业信息匹配
        CompanyInfoCompareParams companyCompareParams = SigningSubjectConvert.INSTANCE.convertCreateReqVO2FadadaCompareParams(createReqVO);
        FadadaResponse fadadaResponse = fadadaContractServiceApi.companyInfoCompare(companyCompareParams);
        if (Objects.isNull(fadadaResponse) || !StringUtils.equals(fadadaResponse.getCode(), FadadaReturnCodeConstants.SUCCESS.getCode().toString())){
            throw exception(COMPANY_NOT_EXISTS);
        }
        // 调用法大大接口自动同步企业信息
        SyncCompanyAutoParams params = SigningSubjectConvert.INSTANCE.convertCreateReqVO2FadadaSyncCompanyParams(createReqVO);
        FadadaSyncCompanyRes fadadaSyncCompanyRes = fadadaContractServiceApi.syncCompanyAuto(params);
        if (Objects.nonNull(fadadaSyncCompanyRes) && StringUtils.isNotBlank(fadadaSyncCompanyRes.getCustomer_id())){
            return fadadaSyncCompanyRes.getCustomer_id();
        }else {
            throw exception(COMPANY_INFO_SYNC_FAILED);
        }
    }

    @Override
    public String createSubjectGetUrl(SigningSubjectCreateReqVO createReqVO) {
        // 调用注册法大大账号
        RegisterAccountParams params = new RegisterAccountParams();
        String openId = "HFGFQY" + createReqVO.getIdCard();
        params.setOpenId(openId);
        params.setAccountType(AccountTypeEnum.COMPANY.getCode());
        String customerId = fadadaAuthServiceApi.accountRegister(params);
        log.info("注册法大大注册账号接口，请求参数：{}，返回参数：{}",JSONObject.toJSONString(params),customerId);
        // 调用法大大获取企业实名地址
        CompanyVerifyUrlParams verifyUrlParams = new CompanyVerifyUrlParams();
        verifyUrlParams.setCustomerId(customerId);
        // 允许页面修改
        verifyUrlParams.setPageModify("1");
        // 自动绑定实名信息
        verifyUrlParams.setCertFlag("1");
        // 企业认证结果回调地址
        verifyUrlParams.setNotifyUrl(COMPANY_VERIFY_NOTIFY_URL);
//        // 企业实名认证同步回调接口
//        verifyUrlParams.setReturnUrl("");
        VerifyUrlRes verifyUrlRes = fadadaAuthServiceApi.getCompanyVerifyUrl(verifyUrlParams);
        log.info("注册法大大获取企业实名地址，请求参数：{}，返回参数：{}", JSONObject.toJSONString(verifyUrlParams),JSONObject.toJSONString(verifyUrlRes));
        if (Objects.isNull(verifyUrlRes)){
            throw exception(SIGNING_SUBJECT_ADD_FAILED);
        }
        // 保存签约主体信息
        SigningSubjectDO signingSubject = SigningSubjectConvert.INSTANCE.convert(createReqVO);
        if (StringUtils.isNotBlank(customerId)){
            signingSubject.setSignatureCode(customerId);
            // 申请默认已驳回  回调成功修改为生效
            signingSubject.setStatus(TWO);
            signingSubject.setTransactionNo(verifyUrlRes.getTransactionNo());
        }
        signingSubjectMapper.insert(signingSubject);
        return verifyUrlRes.getUrl();
    }

    @Override
    public void updateSigningSubject(SigningSubjectUpdateReqVO updateReqVO) {
        // 校验存在
        SigningSubjectDO signingSubject = validateSigningSubjectExists(updateReqVO.getId());
        // 更新
        SigningSubjectDO updateObj = SigningSubjectConvert.INSTANCE.convert(updateReqVO);
        LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
        if (StringUtils.isNotBlank(updateObj.getCompanyName())){
            updateWrapper.set(SigningSubjectDO::getCompanyName, updateObj.getCompanyName());
        }
        if (StringUtils.isNotBlank(updateObj.getCompanyIdCard())){
            updateWrapper.set(SigningSubjectDO::getCompanyIdCard, updateObj.getCompanyIdCard());
        }
        if (StringUtils.isNotBlank(updateObj.getLegal())){
            updateWrapper.set(SigningSubjectDO::getLegal, updateObj.getLegal());
        }
        if (StringUtils.isNotBlank(updateObj.getPhone())){
            updateWrapper.set(SigningSubjectDO::getPhone, updateObj.getPhone());
        }
        if (StringUtils.isNotBlank(updateObj.getIdCard())){
            updateWrapper.set(SigningSubjectDO::getIdCard, updateObj.getIdCard());
        }
        if (StringUtils.isNotBlank(updateObj.getEmail())){
            updateWrapper.set(SigningSubjectDO::getEmail, updateObj.getEmail());
        }
        if (Objects.nonNull(updateObj.getSignSwitch())){
            //开启线上签约 但生效状态非已生效
            if (updateObj.getSignSwitch() && signingSubject.getStatus() != 1){
                throw exception(NOT_ACTIVE_COULD_NOT_OPEN_SWITCH);
            }
            updateWrapper.set(SigningSubjectDO::getSignSwitch, updateObj.getSignSwitch());
        }
        updateWrapper.eq(SigningSubjectDO::getId, updateObj.getId());
        signingSubjectMapper.update(null, updateWrapper);
    }

    @Override
    public void deleteSigningSubject(Long id) {
        // 校验存在
        validateSigningSubjectExists(id);
        // 校验关联房源
        LambdaQueryWrapper<ContractSubjectRoomRefDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ContractSubjectRoomRefDO::getSubjectId, id);
        List<ContractSubjectRoomRefDO> contractSubjectRoomRefDOS = contractSubjectRoomRefMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(contractSubjectRoomRefDOS)){
            throw exception(SIGNING_SUBJECT_EXIST_REL_APARTMENT);
        }
        // 删除
        signingSubjectMapper.deleteById(id);
    }

    private SigningSubjectDO validateSigningSubjectExists(Long id) {
        SigningSubjectDO signingSubjectDO = signingSubjectMapper.selectById(id);
        if (signingSubjectDO == null) {
            throw exception(SIGNING_SUBJECT_NOT_EXISTS);
        }
        return signingSubjectDO;
    }

    @Override
    public SigningSubjectRespVO getSigningSubject(Long id) {
        SigningSubjectDO signingSubjectDO = signingSubjectMapper.selectById(id);
        //查询关联房源
        return relationApartment(signingSubjectDO);
    }

    private SigningSubjectRespVO relationApartment(SigningSubjectDO signingSubjectDO){
        SigningSubjectRespVO respVO = SigningSubjectConvert.INSTANCE.convert(signingSubjectDO);
        //关联房源
        LambdaQueryWrapper<ContractSubjectRoomRefDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ContractSubjectRoomRefDO::getSubjectId, respVO.getId());
        List<ContractSubjectRoomRefDO> contractSubjectRoomRefDOS = contractSubjectRoomRefMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(contractSubjectRoomRefDOS)){
            List<Long> apartmentIds = contractSubjectRoomRefDOS.stream().map(ContractSubjectRoomRefDO::getApartmentId).collect(Collectors.toList());
            CommonResult<List<ApartmentListDto>> listCommonResult = apartmentApi.listByIds(apartmentIds);
            if (Objects.nonNull(listCommonResult)){
                List<ApartmentListDto> data = listCommonResult.getData();
                if (CollectionUtils.isNotEmpty(data)){
                    String relationApartment = data.stream().map(ApartmentListDto::getName).collect(Collectors.joining(","));
                    List<Long> relationApartmentIds = data.stream().map(ApartmentListDto::getId).collect(Collectors.toList());
                    respVO.setRelationApartment(relationApartment);
                    respVO.setRelationApartmentIds(relationApartmentIds);
                }
            }
        }

        return respVO;
    }

    @Override
    public List<SigningSubjectRespVO> getSigningSubjectList() {
        List<SigningSubjectDO> signingSubjectDOS = signingSubjectMapper.selectList();
        List<SigningSubjectRespVO> respVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(signingSubjectDOS)){
            for (SigningSubjectDO signingSubjectDO : signingSubjectDOS) {
                SigningSubjectRespVO respVO = relationApartment(signingSubjectDO);
                respVOList.add(respVO);
            }
        }
        return respVOList;
    }

    void validateSigningSubjectRefApartment(SigningSubjectRefApartmentReqVO reqVO){
        if (CollectionUtils.isNotEmpty(reqVO.getApartmentIds())){
            LambdaQueryWrapper<ContractSubjectRoomRefDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ContractSubjectRoomRefDO::getApartmentId, reqVO.getApartmentIds());
            queryWrapper.ne(ContractSubjectRoomRefDO::getSubjectId, reqVO.getSubjectId());
            List<ContractSubjectRoomRefDO> contractSubjectRoomRefDOS = contractSubjectRoomRefMapper.selectList(queryWrapper);
            if (CollectionUtils.isNotEmpty(contractSubjectRoomRefDOS)){
                throw exception(APARTMENT_ALREADY_REF_OTHER_SUBJECT);
            }
        }
    }

    @Override
    public void relationApartment(SigningSubjectRefApartmentReqVO reqVO) {
        // 校验存在
        validateSigningSubjectExists(reqVO.getSubjectId());
        // 校验公寓是否已关联其他主体
        validateSigningSubjectRefApartment(reqVO);

        //删除原关联
        LambdaQueryWrapper<ContractSubjectRoomRefDO> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(ContractSubjectRoomRefDO::getSubjectId, reqVO.getSubjectId());
        contractSubjectRoomRefMapper.delete(deleteWrapper);

        //保存新关联
        List<ContractSubjectRoomRefDO> contractSubjectRoomRefDOS = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(reqVO.getApartmentIds())){
            List<ContractSubjectRoomRefDO> subjectHouseRefDOS = new ArrayList<>();
            for (Long id : reqVO.getApartmentIds()) {
                ContractSubjectRoomRefDO contractSubjectRoomRefDO = new ContractSubjectRoomRefDO();
                contractSubjectRoomRefDO.setSubjectId(reqVO.getSubjectId());
                contractSubjectRoomRefDO.setApartmentId(id);
                subjectHouseRefDOS.add(contractSubjectRoomRefDO);
            }
            if (CollectionUtils.isNotEmpty(subjectHouseRefDOS)){
                contractSubjectRoomRefDOS.addAll(subjectHouseRefDOS);
            }
        }
        if (CollectionUtils.isNotEmpty(contractSubjectRoomRefDOS)){
            contractSubjectRoomRefMapper.insertBatch(contractSubjectRoomRefDOS);
        }
    }

    @Override
    public PageResult<SigningSubjectRespVO> getSigningSubjectPage(SigningSubjectPageReqVO pageReqVO) {
        Page<SigningSubjectDO> page = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
        LambdaQueryWrapper<SigningSubjectDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(pageReqVO.getCompanyName()), SigningSubjectDO::getCompanyName, pageReqVO.getCompanyName());
        queryWrapper.eq(StringUtils.isNotBlank(pageReqVO.getCompanyIdCard()),SigningSubjectDO::getCompanyIdCard, pageReqVO.getCompanyIdCard());
        queryWrapper.eq(StringUtils.isNotBlank(pageReqVO.getLegal()), SigningSubjectDO::getLegal, pageReqVO.getLegal());
        queryWrapper.like(StringUtils.isNotBlank(pageReqVO.getPhone()), SigningSubjectDO::getPhone, pageReqVO.getPhone());
        queryWrapper.eq(StringUtils.isNotBlank(pageReqVO.getIdCard()), SigningSubjectDO::getIdCard, pageReqVO.getIdCard());
        queryWrapper.eq(StringUtils.isNotBlank(pageReqVO.getEmail()), SigningSubjectDO::getEmail, pageReqVO.getEmail());
        queryWrapper.eq(Objects.nonNull(pageReqVO.getStatus()), SigningSubjectDO::getStatus, pageReqVO.getStatus());
        queryWrapper.eq(Objects.nonNull(pageReqVO.getSignSwitch()), SigningSubjectDO::getSignSwitch, pageReqVO.getSignSwitch());
        page = signingSubjectMapper.selectPage(page, queryWrapper);
        List<SigningSubjectRespVO> subjectRespVOList = new ArrayList<>();
        for (SigningSubjectDO signingSubjectDO : page.getRecords()) {
            SigningSubjectRespVO respVO = relationApartment(signingSubjectDO);
            subjectRespVOList.add(respVO);
        }
        return new PageResult<>(subjectRespVOList,  page.getTotal());
    }

    @Override
    public SigningSubjectDO getSubjectByApartmentId(Long apartmentId) {
        //查询房源主体关联信息
        LambdaQueryWrapper<ContractSubjectRoomRefDO> roomRefQueryWrapper = new LambdaQueryWrapper<>();
        roomRefQueryWrapper.eq(ContractSubjectRoomRefDO::getApartmentId, apartmentId);
        roomRefQueryWrapper.orderByDesc(ContractSubjectRoomRefDO::getCreateTime);
        List<ContractSubjectRoomRefDO> contractSubjectRoomRefDOS = contractSubjectRoomRefMapper.selectList(roomRefQueryWrapper);
        if (CollectionUtils.isEmpty(contractSubjectRoomRefDOS)) {
            throw exception(APARTMENT_NOT_REF_CONTRACT_SUBJECT);
        }
        ContractSubjectRoomRefDO contractSubjectRoomRefDO = contractSubjectRoomRefDOS.get(ZERO);
        if (Objects.isNull(contractSubjectRoomRefDO.getSubjectId())) {
            throw exception(APARTMENT_NOT_REF_CONTRACT_SUBJECT);
        }

        return signingSubjectMapper.selectById(contractSubjectRoomRefDO.getSubjectId());
    }


    @Override
    public List<Long> getRefApartmentList(Long id) {
        LambdaQueryWrapper<ContractSubjectRoomRefDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Objects.nonNull(id), ContractSubjectRoomRefDO::getSubjectId, id);
        List<ContractSubjectRoomRefDO> contractSubjectRoomRefList = contractSubjectRoomRefMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(contractSubjectRoomRefList)){
            return contractSubjectRoomRefList.stream().map(ContractSubjectRoomRefDO::getApartmentId).collect(Collectors.toList());
        }
        return null;
    }


    @Override
    public void authCallback(SigningSubjectAuthCallbackReqVO reqVO) {
        // 查询签约主体信息
        LambdaQueryWrapper<SigningSubjectDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SigningSubjectDO::getSignatureCode, reqVO.getCustomerId());
        queryWrapper.eq(SigningSubjectDO::getTransactionNo, reqVO.getSerialNo());
        SigningSubjectDO signingSubject = signingSubjectMapper.selectOne(queryWrapper);
        if (Objects.nonNull(signingSubject)){
            if (Objects.nonNull(signingSubject.getStatus()) && signingSubject.getStatus().intValue() == ONE){
                // 已经更新实名完成
                return;
            }
            //更新签约主体数据
            LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(SigningSubjectDO::getId, signingSubject.getId());
            updateWrapper.set(SigningSubjectDO::getAuthStatus, reqVO.getStatus());
            if (reqVO.getStatus() == 4){
                // 认证完成
                updateWrapper.set(SigningSubjectDO::getStatus, ONE);
                updateWrapper.set(SigningSubjectDO::getActiveTime, LocalDateTime.now());
                // 调用法大大查询企业实名认证信息
                FindCompanyCertParams params = new FindCompanyCertParams();
                params.setVerifiedSerialNo(signingSubject.getTransactionNo());
                CompanyCertInfoRes companyCertInfo = fadadaAuthServiceApi.findCompanyCertInfo(params);
                log.info("调用法大大查询企业实名认证信息，请求参数：{}，返回参数：{}", JSONObject.toJSONString(params), JSONObject.toJSONString(companyCertInfo));
                if (Objects.nonNull(companyCertInfo)){
                    updateWrapper.set(SigningSubjectDO::getVerifyType, companyCertInfo.getCompany().getVerifyType());
                    updateWrapper.set(SigningSubjectDO::getOrganizationType, companyCertInfo.getCompany().getOrganizationType());
                }
            }
            signingSubjectMapper.update(null, updateWrapper);
        }
    }


    @Override
    public String getAutoSignUrl(Long id) {
        SigningSubjectDO signingSubject = validateSigningSubjectExists(id);

        //生成交易号
        String timeKey = LocalDate.now().format(DateTimeFormatter.ofPattern(DateUtils.FORMAT_NO_DATE));
        String code = RedisUtils.queryMaxCode(AUTO_SIGN_TRANSACTION_REDIS_KEY, timeKey);
        String transactionId = AUTO_SIGN_TRANSACTION_PREFIX + signingSubject.getId() + UNDERLINE + timeKey + code;

        //生成线上授权委托书的合同编号
        String autoContractId = AUTO_SIGN_CONTRACT_NO_PREFIX + signingSubject.getId() + UNDERLINE + timeKey + code;

        BeforeAuthSignParams params = new BeforeAuthSignParams();
        //平台自定义唯一交易号
        params.setTransactionId(transactionId);
        //1:授权自动签（目前只能填1）
        params.setAuthType("1");
        //指该份线上授权委托书的合同编号，自定义即可
        params.setContractId(autoContractId);
        //传入注册返回的个人或企业客户编号
        params.setCustomerId(signingSubject.getSignatureCode());
        //异步通知签署结果地址
        params.setNotifyUrl(AUTO_SIGN_NOTIFY_URL);
//        //同步通知签署结果url
//        params.setReturnUrl("");
        String url = fadadaContractServiceApi.beforeAuthsign(params);
        log.info("获取法大大自动签约地址，请求参数：{}，返回参数：{}",JSONObject.toJSONString(params),url);

        //更新签约主体数据
        LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SigningSubjectDO::getId, signingSubject.getId());
        updateWrapper.set(SigningSubjectDO::getAutoSignTransactionNo, transactionId);
        updateWrapper.set(SigningSubjectDO::getAutoSignContractNo, autoContractId);
        // 自动签约授权状态 已申请
        updateWrapper.set(SigningSubjectDO::getAutoSignStatus, ONE);
        signingSubjectMapper.update(null, updateWrapper);

        return url;
    }

    @Override
    public void autoSignCallback(AutoSignCallbackReqVO reqVO) {
        // 查询签约主体信息
        LambdaQueryWrapper<SigningSubjectDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SigningSubjectDO::getAutoSignTransactionNo, reqVO.getTransaction_id());
        SigningSubjectDO signingSubject = signingSubjectMapper.selectOne(queryWrapper);

        if (Objects.isNull(signingSubject)){
            log.info("授权自动签约回调接口，通过法大大交易号未查询到对应签约主体数据，回调数据：{}", JSONObject.toJSONString(reqVO));
            return;
        }

        // 更新签约主体数据
        LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SigningSubjectDO::getId, signingSubject.getId());
        if ("3000".equals(reqVO.getResult_code())){
            // 授权成功
            updateWrapper.set(SigningSubjectDO::getAutoSignStatus, TWO);
            updateWrapper.set(SigningSubjectDO::getViewPdfUrl, reqVO.getViewpdf_url());
            updateWrapper.set(SigningSubjectDO::getDownloadUrl, reqVO.getDownload_url());
            updateWrapper.set(SigningSubjectDO::getAutoSignActiveTime, LocalDateTime.now());
        }else {
            updateWrapper.set(SigningSubjectDO::getAutoSignStatus, THREE);
        }
        updateWrapper.set(SigningSubjectDO::getAutoSignDesc, reqVO.getResult_desc());
        signingSubjectMapper.update(null, updateWrapper);
    }


    @Override
    public void addSubjectSignature(SigningSubjectAddSignatureReqVO reqVO) {
        SigningSubjectDO signingSubject = validateSigningSubjectExists(reqVO.getId());
        if (4 != signingSubject.getAuthStatus()){
            throw exception(CONTRACT_SUBJECT_NOT_AUTHENTICATION);
        }

        AddSignatureParams params = new AddSignatureParams();
        params.setCustomerId(signingSubject.getSignatureCode());
        params.setImgUrl(reqVO.getSignatureUrl());
        AddSignatureRes addSignatureRes = fadadaContractServiceApi.addSignature(params);
        log.info("上传企业印章请求法大大，请求参数：{}，返回参数：{}", JSONObject.toJSONString(params), JSONObject.toJSONString(addSignatureRes));
        if (Objects.nonNull(addSignatureRes) && StringUtils.isNotBlank(addSignatureRes.getSignature_id())){
            // 更新签约主体数据
            LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(SigningSubjectDO::getId, signingSubject.getId());
            updateWrapper.set(SigningSubjectDO::getSealCodeId, addSignatureRes.getSignature_id());
            signingSubjectMapper.update(null, updateWrapper);
        }
    }


    @Override
    public void syncAutoSign(Long id) {
        SigningSubjectDO signingSubject = validateSigningSubjectExists(id);
        if (Objects.nonNull(signingSubject.getAuthStatus()) && signingSubject.getAutoSignStatus().intValue() == ZERO.intValue()){
            throw exception(CONTRACT_SUBJECT_NOT_AUTH_AUTO_SIGN);
        }
        GetAuthStatusParams params = new GetAuthStatusParams();
        params.setCustomerId(signingSubject.getSignatureCode());
        GetAuthStatusRes authStatus = fadadaContractServiceApi.getAuthStatus(params);
        log.info("请求法大大查询授权自动签约状态，请求参数：{}，返回参数：{}", JSONObject.toJSONString(params), JSONObject.toJSONString(authStatus));
        if (Objects.nonNull(authStatus) && "1".equals(authStatus.getStatus())){
            // 更新签约主体数据
            LambdaUpdateWrapper<SigningSubjectDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(SigningSubjectDO::getId, signingSubject.getId());
            updateWrapper.set(SigningSubjectDO::getAutoSignStatus, TWO);
            signingSubjectMapper.update(null, updateWrapper);
        }
    }


    @Override
    public Boolean onlineSignCheck(Long roomId, String templateType) {
        // 查询房源房间信息
        CommonResult<RoomHouseRespVo> roomHouseinfoById = roomHouseApi.getRoomHouseinfoById(roomId);
        if (Objects.isNull(roomHouseinfoById)) {
            throw exception(ROOM_NOT_EXIST);
        }
        if (Objects.isNull(roomHouseinfoById.getData())) {
            throw exception(ROOM_NOT_EXIST);
        }
        RoomHouseRespDTO roomHouseResp = RoomServerConvert.INSTANCE.converRespVo2RespDto(roomHouseinfoById.getData());

        // 查询绑定签约主体
        SigningSubjectDO signingSubjectDO = getSubjectByApartmentId(roomHouseResp.getApartmentId());
        if (Objects.isNull(signingSubjectDO)) {
            throw exception(CONTRACT_SUBJECT_NOT_EXIST);
        }
        if (Objects.isNull(signingSubjectDO.getStatus()) ||
                signingSubjectDO.getStatus().intValue() != SigningSubjectStatusEnum.EFFECTIVE.getCode().intValue()) {
            //主体未认证
            throw exception(CONTRACT_SUBJECT_NOT_AUTHENTICATION);
        }
        if (!signingSubjectDO.getSignSwitch()){
            // 主体未开启线上签约
            throw exception(SUBJECT_NOT_OPEN_ONLINE_SIGN);
        }

        // 查询绑定合同模板
        ContractTemplateDO contractTemplateDO = contractTemplateService.getTemplateByRoomId(roomHouseResp.getApartmentId(), roomHouseResp.getIsWhole() ? ZERO : ONE, templateType);
        if (Objects.isNull(contractTemplateDO)) {
            //合同模板不存在
            throw exception(CONTRACT_TEMPLATE_NOT_EXISTS);
        }

        return true;
    }
}
